#if UNITY_EDITOR
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;

using MetaTable;
using UnityEngine.UI;
using UnityEditor;
using Pangoo.Common;

namespace MetaTable
{
    public class MetaTableSingleOverviewWrapper<TOverview, TDetalRowWrapper, TTableRowWrapper, TNewRowWrapper, TRow> : IMetaTableSingleOverviewWrapper
            where TDetalRowWrapper : MetaTableDetailRowWrapper<TOverview, TRow>, new()
            where TTableRowWrapper : MetaTableRowWrapper<TOverview, TNewRowWrapper, TRow>, new()
            where TNewRowWrapper : MetaTableNewRowWrapper<TOverview, TRow>, new()
            where TOverview : MetaTableOverview
            where TRow : MetaTableUnityRow, new()

    {

        public IMetaTableEditor Editor { get; set; }

        [ShowInInspector]
        [ReadOnly]
        public TOverview Overview { get; set; }



        OdinMenuEditorWindow m_MenuWindow;

        public OdinMenuEditorWindow MenuWindow
        {
            get
            {
                return m_MenuWindow;
            }
            set
            {
                m_MenuWindow = value;
            }

        }



        public OdinMenuTree Tree { get; set; }

        private static OdinEditorWindow m_CreateWindow;

        [Searchable]
        [TableList(IsReadOnly = true, AlwaysExpanded = true, ShowPaging = true, NumberOfItemsPerPage = 25)]
        [ShowInInspector]
        [LabelText("行数据")]
        public readonly List<TTableRowWrapper> m_AllWrappers = new List<TTableRowWrapper>();

        private Dictionary<string, OdinMenuItem> MenuItemDict = new Dictionary<string, OdinMenuItem>();

        public string MenuDisplayName { get; set; }


        public void Init()
        {
            foreach (var kv in MenuItemDict)
            {
                Tree.MenuItems.Remove(kv.Value);
            }
            MenuItemDict.Clear();
            m_AllWrappers.Clear();
            List<TTableRowWrapper> tmpRows = new List<TTableRowWrapper>();

            if (Overview == null) return;

            tmpRows.AddRange(Overview.UnityBaseRows.Select(x =>
            {
                if (x == null) return null;

                var detailWrapper = new TDetalRowWrapper();
                detailWrapper.Overview = Overview;
                detailWrapper.UnityRow = x as TRow;
                detailWrapper.MenuWindow = MenuWindow;
                detailWrapper.Editor = Editor;
                Editor.SetDetailWrapper(detailWrapper.Uuid, detailWrapper);

                var wrapper = new TTableRowWrapper();
                wrapper.Overview = Overview;
                wrapper.UnityRow = x as TRow;
                wrapper.MenuWindow = MenuWindow;
                wrapper.DetailWrapper = detailWrapper;
                wrapper.Editor = Editor;
                Editor.SetRowWrapper(wrapper.Uuid, wrapper);

                return wrapper;
            }).ToList());

            tmpRows = tmpRows.Where(o => o != null).ToList();

            foreach (var wrapper in tmpRows)
            {
                var itemMenuKey = wrapper.Uuid;
                // Debug.Log($"wrapper:{wrapper}");
                var itemDisplayName = $"{MenuDisplayName}-{wrapper.UuidShort}-{wrapper.Name}";
                var customMenuItem = new OdinMenuItem(Tree, itemDisplayName, wrapper.DetailWrapper);
                MenuItemDict.Add(itemMenuKey, customMenuItem);
                Tree.AddMenuItemAtPath(MenuPath, customMenuItem);
            }
            m_AllWrappers.AddRange(tmpRows);
        }

        public void InitWrappers()
        {
            foreach (var kv in MenuItemDict)
            {
                Tree.MenuItems.Remove(kv.Value);
            }
            MenuItemDict.Clear();
            m_AllWrappers.Clear();
            List<TTableRowWrapper> tmpRows = new List<TTableRowWrapper>();

            tmpRows.AddRange(Overview.UnityBaseRows.Select(x =>
            {
                if (x == null) return null;

                var detailWrapper = new TDetalRowWrapper();
                detailWrapper.Overview = Overview;
                detailWrapper.UnityRow = x as TRow;
                detailWrapper.MenuWindow = MenuWindow;
                detailWrapper.Editor = Editor;
                Editor.SetDetailWrapper(detailWrapper.Uuid, detailWrapper);

                var wrapper = new TTableRowWrapper();
                wrapper.Overview = Overview;
                wrapper.UnityRow = x as TRow;
                wrapper.MenuWindow = MenuWindow;
                wrapper.DetailWrapper = detailWrapper;
                wrapper.Editor = Editor;
                Editor.SetRowWrapper(wrapper.Uuid, wrapper);

                return wrapper;
            }).ToList());

            tmpRows = tmpRows.Where(o => o != null).ToList();

            foreach (var wrapper in tmpRows)
            {
                var itemMenuKey = wrapper.Uuid;
                // Debug.Log($"wrapper:{wrapper}");
                var itemDisplayName = $"{MenuDisplayName}-{wrapper.UuidShort}-{wrapper.Name}";
                var customMenuItem = new OdinMenuItem(Tree, itemDisplayName, wrapper.DetailWrapper);
                MenuItemDict.Add(itemMenuKey, customMenuItem);
                Tree.AddMenuItemAtPath(MenuDisplayName, customMenuItem);
            }
            m_AllWrappers.AddRange(tmpRows);



        }

        public virtual bool ShowNewButton => true;

        IMetaTableOverview IMetaTableSingleOverviewWrapper.Overview
        {
            get
            {
                return Overview;
            }
            set
            {
                Overview = value as TOverview;
            }
        }

        public string MenuPath { get; set; }
        public MetaTableConfig Config { get; set; }
        public string OverviewName { get; set; }

        [Button("新建行")]
        [ShowIf("@this.ShowNewButton")]
        public void NewRow()
        {
            if (Overview == null)
            {
                return;
            }

            var newTypeWrapper = new TNewRowWrapper();
            newTypeWrapper.EnableEditOverview = true;
            newTypeWrapper.Overview = Overview;
            newTypeWrapper.UnityRow = ScriptableObject.CreateInstance<TRow>();
            newTypeWrapper.UnityRow.BaseRow.Uuid = UuidUtility.GetNewUuid();
            Debug.Log($"typeof:{newTypeWrapper.GetType()}");
            m_CreateWindow = OdinEditorWindow.InspectObject(newTypeWrapper);

            newTypeWrapper.OpenWindow = m_CreateWindow;
            newTypeWrapper.AfterCreate = OnAfterCreate;
            OnNewRowPostprocess(newTypeWrapper);
        }
        public virtual void OnNewRowPostprocess(TNewRowWrapper newRowWrapper)
        {
        }

        [Button("刷新行")]
        public void RefreshRows()
        {
            Overview.RefreshRows();
        }


        void OnAfterCreate(string uuid)
        {
            InitWrappers();
            if (m_CreateWindow != null)
            {
                m_CreateWindow.Close();
            }


        }

        [Button("创建Overview")]
        public void CreateOverview()
        {
            if (Overview != null) return;

            Overview = ScriptableObject.CreateInstance(OverviewName) as TOverview;
            Overview.Config = Config;
            AssetDatabase.CreateAsset(Overview, Overview.FileName);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }

    }
}
#endif